package com.xb.loan.cashier.biz.task.wechat;

import com.xb.loan.cashier.biz.dao.bean.CashierPayChannel;
import com.xb.loan.cashier.biz.pay.wechat.WeChatConst;
import com.xb.loan.cashier.biz.pay.wechat.util.RandomStringGenerator;
import com.xb.loan.cashier.biz.pay.wechat.util.WeChatSignature;
import com.xb.loan.cashier.biz.pay.wechat.util.httpClient.HttpsCerRequest;
import com.xb.loan.cashier.biz.service.CashierChargeOrderService;
import com.xb.loan.cashier.biz.service.CashierPayChannelService;
import com.xb.loan.cashier.biz.service.CashierPlatPaytypeService;
import com.xb.loan.cashier.biz.task.ThirdQueryChargeTask;
import com.xb.loan.cashier.biz.task.plat.PushChargeTask;
import com.xb.loan.cashier.biz.util.XMLUtil;
import com.xb.loan.cashier.service.constant.ICashierEnumConst;
import com.xb.loan.util.DateHelper;
import com.xb.loan.util.json.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 微信查询交易订单任务
 *
 */
@Component(value="weChatQueryChargeTask")
@Scope(value="prototype")
public class WeChatQueryChargeTask extends ThirdQueryChargeTask {
    
    private static final Logger log = LoggerFactory.getLogger(WeChatQueryChargeTask.class);

    @Autowired
    private CashierChargeOrderService cashierChargeOrderService;
    @Autowired
    private CashierPayChannelService cashierPayChannelService;
    @Autowired
    private CashierPlatPaytypeService cashierPlatPaytypeService;
    
    /**
     * 当商户后台、网络、服务器等出现异常，商户系统最终未接收到支付通知
     * 1.根据商户订单号查询订单是否交易成功
     * 2.校验微信返回的xml数据是否有被篡改过
     * 3.根据微信返回的状态修改订单状态为成功或失败
     */
    @Override
	public void execute() {
        
	    log.info("WeChatQueryChargeTask.execute 开始处理订单 orderId="+cashierChargeOrder.getOrderId()+
	            ",platId="+cashierChargeOrder.getPlatId()+",partnerId="+
	            cashierChargeOrder.getPartnerId()+",payChannelType="+cashierChargeOrder.getPayChannelType());
	    
        //查询支付渠道基本信息
        CashierPayChannel cpc = cashierPayChannelService.queryByChannelId(cashierChargeOrder.getPayChannelId());
        
        if (cpc == null) {
            log.info("WeChatQueryChargeTask.execute 支付渠道信息不存在 platId="+
                    cashierChargeOrder.getPlatId()+",payChannelType="+cashierChargeOrder.getPayChannelType());
            return;
        }
        
        Map<String, Object> map = new HashMap<String , Object>();
        
        String appid = JsonUtils.fromJson(cpc.getJsonConfig()).get("appid").toString();
        String queryUrl = cpc.getQueryUrl() + WeChatConst.TRADE_URL_ORDERQUERY;
        
        map.put("appid", appid);
        //微信支付分配的商户号
        map.put("mch_id", cpc.getChannelUser());
        
        //微信订单号，跟商户订单号只需要传一个
        //map.put("transaction_id", cashierChargeOrder.getChannelOrderId());
        
        //商户系统内部的订单号,32个字符内
        map.put("out_trade_no", cashierChargeOrder.getOrderId());
        
        //随机字符串，不长于32位
        map.put("nonce_str", RandomStringGenerator.getRandomStringByLength(32));
        
        //对请求参数签名
        String paySign = WeChatSignature.getSign(map, cpc.getMd5Key());
        //对请求参数签名
        map.put("sign", paySign);
        
        try {
            
            //请求返回xml
            String orderqueryResult = new HttpsCerRequest().sendPost(queryUrl , map);
            
            //先验证签名是否被篡改
            boolean verify_result = WeChatSignature.checkIsSignValidFromResponseString(orderqueryResult , cpc.getMd5Key());
            
            if(!verify_result){
                //签名验证失败
                log.info("WeChatQueryChargeTask 查询订单返回验证失败=" + verify_result);
                return ;
            }
            
            //把xml数据转换为map对象，获取订单信息
            Map<String, Object> resultMap = XMLUtil.parse(orderqueryResult.getBytes(WeChatConst.TRADE_CHARSET_UTF8));
            
            //业务结果，有可能为空
            Object result_code = resultMap.get("result_code");
            
            if(null == result_code){
                //交易状态未知
                log.info("WeChatQueryChargeTask 业务处理结果未返回" + orderqueryResult);
                return ;
            }
            
            //处理订单状态
            dealOrderStatus(resultMap);
            
        } catch (Exception e) {
            
            log.error(e.getMessage(), e);
        }
	}
    
    
    private void dealOrderStatus(Map<String, Object> resultMap){
        
        //总金额
        double totalFee = Double.parseDouble((String)resultMap.get("total_fee"));
        
        //微信返回的金额为分，数据库存储的金额为元
        if (totalFee != cashierChargeOrder.getMoney() * 100) {
            
            log.info("WeChatQueryChargeTask 微信返回金额与收银台不一致  orderId="+cashierChargeOrder.getOrderId()+
                    ",wechatTotalFee="+totalFee+",money="+cashierChargeOrder.getMoney());
            return ;
        }
        
        /*
         *  SUCCESS—支付成功
         *  REFUND—转入退款
         *  NOTPAY—未支付
         *  CLOSED—已关闭
         *  REVOKED—已撤销（刷卡支付）
         *  USERPAYING--用户支付中
         *  PAYERROR--支付失败
         */
        String tradeState = (String)resultMap.get("trade_state");
        
        //业务处理状态
        int status = 0;
        
        if(WeChatConst.TRADE_STATE_SUCCESS.equals(tradeState)){
            //支付成功
            status = ICashierEnumConst.CashierChargeStatus.SUCCESS.getStatus();
            
        }else if(WeChatConst.TRADE_STATE_PAYERROR.equals(tradeState) || 
                WeChatConst.TRADE_STATE_CLOSED.equals(tradeState) ){
            
            //已关闭和支付失败订单
            status = ICashierEnumConst.CashierChargeStatus.FAIL.getStatus();
            
        }else{
            
            //未知的交易状态
            log.info("WeChatQueryChargeTask 其它交易状态:" + tradeState);
            return ;
        }
        
        //微信支付订单号
        String transactionId = (String)resultMap.get("transaction_id");
        //支付完成时间，格式为yyyyMMddHHmmss
        String timeEnd = (String)resultMap.get("time_end");
        
        try {
            
            //转换交易时间格式为yyyy-MM-dd HH:mm:ss
            Date tradeTime = DateHelper.convertToDate("yyyyMMddHHmmss", timeEnd);
            timeEnd = DateHelper.DateToString(null, tradeTime);
            
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //错误代码
        String errorCode = (String)resultMap.get("err_code");
        String errorMsg = (String)resultMap.get("err_code_des");
        
        int res = cashierChargeOrderService.updateByOrderId(null, null, cashierChargeOrder.getOrderId(), timeEnd, 
                status, transactionId , errorCode, errorMsg);
        
        if(res > 0){
            
            PushChargeTask pct = (PushChargeTask)ctx.getBean("pushChargeTask");
            cashierChargeOrder.setStatus(status);
            pct.setCashierChargeOrder(cashierChargeOrder);
            pct.execute();
            
            log.info("WeChatQueryChargeTask.dealOrderStatus 更新状态status="+ status +
                    ",orderId=" + cashierChargeOrder.getOrderId()+
                    ",platId=" + cashierChargeOrder.getPlatId()+
                    ",partnerId=" + cashierChargeOrder.getPartnerId());
        }
    }
}
